'use strict'
exports.main = async (event, context) => {
  /**
	 * 检测升级 使用说明
	 * 上传包：
	 * 1. 根据传参，先检测传参是否完整，appid appVersion wgtVersion 必传
	 * 2. 先从数据库取出所有该平台（从上下文读取平台信息，默认 Andriod）的所有线上发行更新
	 * 3. 再从所有线上发行更新中取出版本最大的一版。如果可以，尽量先检测wgt的线上发行版更新
	 * 4. 使用上步取出的版本包的版本号 和传参 appVersion、wgtVersion 来检测是否有更新，必须同时大于这两项，否则返回暂无更新
	 * 5. 如果库中 wgt包 版本大于传参 appVersion，但是不满足 min_uni_version < appVersion，则不会使用wgt更新，会接着判断库中 app包version 是否大于 appVersion
	 */

  let {
    appid,
    appVersion,
    wgtVersion
  } = event

  const platform_Android = 'Android'
  const platform_iOS = 'iOS'
  const package_app = 'native_app'
  const package_wgt = 'wgt'
  const app_version_db_name = 'opendb-app-versions'

  let platform = platform_Android

  // 云函数URL化请求
  if (event.headers) {
    let body
    try {
      if (event.httpMethod.toLocaleLowerCase() === 'get') {
        body = event.queryStringParameters
      } else {
        body = JSON.parse(event.body)
      }
    } catch (e) {
      return {
        code: 500,
        msg: '请求错误'
      }
    }

    appid = body.appid
    appVersion = body.appVersion
    wgtVersion = body.wgtVersion

    platform = /iPhone|iPad/.test(event.headers) ? platform_iOS : platform_Android
  } else if (context.OS) {
    platform = context.OS === 'android'
      ? platform_Android
      : context.OS === 'ios'
        ? platform_iOS
        : platform_Android
  }

  if (appid && appVersion && wgtVersion && platform) {
    const collection = uniCloud.database().collection(app_version_db_name)

    const record = await collection.where({
      appid,
      platform,
      stable_publish: true
    })
      .orderBy('create_date', 'desc')
      .get()

    if (record && record.data && record.data.length > 0) {
      const appVersionInDb = record.data.find(item => item.type === package_app) || {}
      const wgtVersionInDb = record.data.find(item => item.type === package_wgt) || {}
      const hasAppPackage = !!Object.keys(appVersionInDb).length
      const hasWgtPackage = !!Object.keys(wgtVersionInDb).length

      // 取两个版本中版本号最大的包，版本一样，使用wgt包
      const stablePublishDb = hasAppPackage
        ? hasWgtPackage
          ? compare(wgtVersionInDb.version, appVersionInDb.version) >= 0
            ? wgtVersionInDb
            : appVersionInDb
          : appVersionInDb
        : wgtVersionInDb

      const {
        version,
        min_uni_version
      } = stablePublishDb

      // 库中的version必须满足同时大于appVersion和wgtVersion才行，因为上次更新可能是wgt更新
      const appUpdate = compare(version, appVersion) === 1 // app包可用更新
      const wgtUpdate = compare(version, wgtVersion) === 1 // wgt包可用更新

      if (Object.keys(stablePublishDb).length && appUpdate && wgtUpdate) {
        // 判断是否可用wgt更新
        if (min_uni_version && compare(min_uni_version, appVersion) < 1) {
          return {
            code: 101,
            message: 'wgt更新',
            ...stablePublishDb
          }
        } else if (hasAppPackage && compare(appVersionInDb.version, appVersion) === 1) {
          return {
            code: 102,
            message: '整包更新',
            ...appVersionInDb
          }
        }
      }

      return {
        code: 0,
        message: '当前版本已经是最新的，不需要更新'
      }
    }

    return {
      code: -101,
      message: '暂无更新或检查appid是否填写正确'
    }
  }

  return {
    code: -102,
    message: '请检查传参是否填写正确'
  }
}

/**
 * 对比版本号，如需要，请自行修改判断规则
 * 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
 * @param {Object} v1
 * @param {Object} v2
 * v1 > v2 return 1
 * v1 < v2 return -1
 * v1 == v2 return 0
 */
function compare (v1 = '0', v2 = '0') {
  v1 = String(v1).split('.')
  v2 = String(v2).split('.')
  const minVersionLens = Math.min(v1.length, v2.length)

  let result = 0
  for (let i = 0; i < minVersionLens; i++) {
    const curV1 = Number(v1[i])
    const curV2 = Number(v2[i])

    if (curV1 > curV2) {
      result = 1
      break
    } else if (curV1 < curV2) {
      result = -1
      break
    }
  }

  if (result === 0 && (v1.length !== v2.length)) {
    const v1BiggerThenv2 = v1.length > v2.length
    const maxLensVersion = v1BiggerThenv2 ? v1 : v2
    for (let i = minVersionLens; i < maxLensVersion.length; i++) {
      const curVersion = Number(maxLensVersion[i])
      if (curVersion > 0) {
        v1BiggerThenv2 ? result = 1 : result = -1
        break
      }
    }
  }

  return result
}
